import os
import pandas as pd
import unicodedata as ud
from pandas import DataFrame
from xlsxwriter.utility import xl_range
DIR_ADMISSION_SCORE_PAGES = './raw_pages/投档线'
DIR_SCORE_RANK_TABLE_PAGES = './raw_pages/一分一档表'
DIR_ADMISSION_SCORE_DATA = './data/admission_score'
DIR_SCORE_RANK_TABLE_DATA = './data/rank_score_table'
DIR_RELEASE = './release'
PATH_USTC_LOGO = './image/ustc_logo_fig_2100x2100.jpg'

MAX_SCORE = 750
MIN_SCORE = 0

ADMISSION_DTYPES = {
    '院校代码': 'object',
    '院校名称': 'object',
    '年份': 'Int64',
    '批次': 'object',
    '类别': 'object', # 文史类或理工类
    '专业组': 'object',
    '投档线': 'Int64',
}

# 需要在表中提取的列名
ADMISSION_FILTER_NAMES = {
    '院校代码': ['院校代号', '院校代码'],
    '院校名称': ['院校名称'],
    '专业组': ['专业组', '专业组名称'],
    '文史类': ['文史类', '文史类投档线'],
    '理工类': ['理工类', '理工类投档线'],
    '投档线': ['投档最低分']
}

ADMISSION_COLUMNS_NAMES = {
    '院校代码': '院校代码',
    '院校名称': '院校名称',
    '年份': '年份',
    '批次': '批次',
    '类别': '类别',
    '专业组': '专业组',
    '投档线': '投档线',
}

SCORE_RANK_DTYPES = {
    '年份': 'Int64',
    '类别': 'object',  # 文史类或理工类
    '分值': 'Int64',
    '人数': 'Int64',
    '累计人数': 'Int64',
    '名次': 'Int64'
}

# 一分一档表中需要的列，以及列在HTML中对应的可能的名字
SCORE_RANK_COLUMNS_NAMES = {
    '分值': ['分值', '总分'],
    '人数': ['人数'],
    '累计人数': ['累计人数'],
    '名次': ['名次']
}

BATCH_NAMES = {
    '本科普通批': 0,
    '本科第一批': 1,
    '本科第二批': 2,
}

BATCH_SHORT_NAMES = {
    '普通批': 0,
    '一本': 1,
    '二本': 2,
}

SUBJECT_NAMES = {
    '理工类': 'science',
    '文史类': 'arts',
    '物理科目组': 'science',
    '历史科目组': 'arts',
    '物理类': 'science',
    '历史类': 'arts',
}

def batch_name(batch):
    for name, b in BATCH_NAMES.items():
        if b == batch:
            return name
    raise ValueError(f'未知的批次{batch}')

def batch_short_name(batch):
    for name, b in BATCH_SHORT_NAMES.items():
        if b == batch:
            return name
    raise ValueError(f'未知的批次{batch}')

def admission_data_path(year, batch, subject, ext='.csv'):
    return os.path.join(
        DIR_ADMISSION_SCORE_DATA,
        f'{year}_batch{batch}_{subject}_admission_score' + ext
    )

def admission_all_in_one_path(ext='.csv'):
    return os.path.join(
        DIR_ADMISSION_SCORE_DATA,
        f'admission_score_all' + ext
    )

def score_rank_data_path(year, subject, ext='.csv'):
    return os.path.join(
        DIR_SCORE_RANK_TABLE_DATA,
        f'{year}_rank_score_table_{subject}' + ext
    )

def score_rank_all_in_one_path(ext='.csv'):
    return os.path.join(
        DIR_SCORE_RANK_TABLE_DATA,
        f'rank_score_table_all' + ext
    )

def rank_file_path(years, batch):
    return os.path.join(DIR_RELEASE,
        f'{batch_short_name(batch)}高校历年录取名次趋势表（{min(years)}年~{max(years)}年）.xlsx')

# 新增获取批次名称的函数
def get_batch_name(batch_id):
    for name, b in BATCH_NAMES.items():
        if b == batch_id:
            return name
    return f"批次{batch_id}"

# 新增获取类别名称的函数
def get_subject_name(subject_id):
    for name, s in SUBJECT_NAMES.items():
        if s == subject_id:
            return name
    return subject_id

def east_asian_len(text):
    EAW_MAP = {"Na": 1, "N": 1, "W": 2, "F": 2, "H": 1, "A": 1}
    return sum([EAW_MAP.get(ud.east_asian_width(c), 1) for c in text])

def write_to_excel_table(df: DataFrame, writer, sheet_name, title, startrow=0, startcol=0):
    # 写入数据
    df.to_excel(writer, sheet_name=sheet_name, startrow=startrow+2, header=False, index=False)
    worksheet = writer.sheets[sheet_name]
    (nrow, ncol) = df.shape

    title_row = startrow
    header_row = startrow + 1
    data_row = startrow + 2
    end_row = data_row + nrow - 1
    data_col = startcol
    end_col = data_col + ncol - 1

    # 自定义列头
    column_settings = [{'header': col} for col in df.columns]
    worksheet.add_table(header_row, data_col, end_row, end_col, {'columns': column_settings})
    # 用east_asian_len计算所有字符串显示长度
    value_len = df.applymap(lambda x: east_asian_len(str(x))).max()
    # 数据头的长度要+2（用于显示筛选箭头）
    header_len = df.columns.to_series().map(lambda x: east_asian_len(str(x))) + 2
    # 最终长度+1（两边边界）
    columns_len = pd.concat([value_len, header_len], axis=1).max(axis=1) + 1
    # 设置最大最小值
    columns_len.clip(4, 24, inplace=True)
    # 设置列宽
    for i, col_len in enumerate(columns_len):
        col = data_col + i
        worksheet.set_column(col, col, col_len)
    
    workbook = writer.book
    merge_format = workbook.add_format({
    'font_name': '等线',
    'font_size': 16,
    'font_color': 'white',
    'bg_color': '#4F81BD',
    'bold': 1,
    'bottom': 6,   # ==== 双边框线
    'bottom_color': 'white',
    'align': 'center',
    'valign': 'vcenter'
    })
    worksheet.merge_range(title_row, data_col, title_row, end_col, title, merge_format)
    return header_row, data_col, end_row, end_col
